﻿using System.Collections.Generic;
using Microsoft.Xna.Framework.Net;
using TNCGameEngine.InternalHelpers;

namespace TNCGameEngine.Network.Data
{
    /// <summary>
    /// Defines a compressed data reader via the network.
    /// </summary>
    public abstract class CompressedReader<T>
    {

        #region "Properties"

        private int readcount = 0;
        /// <summary>
        /// The current number of bytes read in.
        /// </summary>
        /// <remarks>Gets the number of bytes read since the last BeginRead().</remarks>
        public int ReadCount
        {
            get { return this.readcount; }
        }

        #endregion

        #region "Variables"

        private PacketReader reader = null;

        #endregion
                
        #region "Methods"

        /// <summary>
        /// The method that needs to be called by the derived constructor.
        /// </summary>
        /// <param name="writer">The packet reader that should be written to.</param>
        protected void PreInitialize(PacketReader reader)
        {
            this.reader = reader;
        }

        /// <summary>
        /// Reads a batch of compressed bytes and converts them to a list of bool values.
        /// </summary>
        /// <param name="num">Number of bool values to read.</param>
        /// <returns>A list of successully read bool values.</returns>
        protected List<bool> ReadBools(int num)
        {

            List<bool> list = new List<bool>(num);

            try
            {

                int count = num;
                byte b = 0;

                while (count >= 8)
                {

                    b = this.reader.ReadByte();

                    list.Add(this.CheckBitByValue(b, 1));
                    list.Add(this.CheckBitByValue(b, 2));
                    list.Add(this.CheckBitByValue(b, 4));
                    list.Add(this.CheckBitByValue(b, 8));
                    list.Add(this.CheckBitByValue(b, 16));
                    list.Add(this.CheckBitByValue(b, 32));
                    list.Add(this.CheckBitByValue(b, 64));
                    list.Add(this.CheckBitByValue(b, 128));
                    
                    count -= 8;
                    
                }

                if (count > 0)
                {

                    b = this.reader.ReadByte();
                    for (byte j = 0; j < count; j++)
                    {
                        list.Add(this.CheckBitByValue(b, Maths.Pow2B(j)));
                    }
                    
                }
                
            }
            catch {  }

            return list;

        }

        private bool CheckBitByValue(byte x, byte val)
        {
            return ((x &= val) == val);
        }

        /// <summary>
        /// Reads a seed for a random number generator that was generated by the packet writer.
        /// </summary>
        /// <returns>The newly generated seed.</returns>
        protected int ReadAndGetRandomSeed()
        {
            return this.reader.ReadInt32();
        }

        //protected float ReadPackedFloat()
        //{
        //    uint i = this.reader.ReadUInt32();
        //    HalfUtil.
        //    this.reader.ReadHa(h.PackedValue);
        //}

        //protected Vector2 ReadPackedVector2()
        //{
        //    HalfVector2 h = new HalfVector2(v);
        //    this.reader.Read(h.PackedValue);
        //}

        //protected Vector3 ReadPackedVector3()
        //{
        //    HalfVector4 h = new HalfVector2(v);
        //    this.reader.Read(h.PackedValue);
        //}

        //protected Vector4 ReadPackedVector4()
        //{
        //    HalfVector4 h = new HalfVector4(v);
        //    this.reader.Read(h.PackedValue);
        //}
        
        #endregion
        
    }

}